package sg.edu.nus.iss.ooad.jass.dao.file;

import java.util.ArrayList;
import java.util.List;
import java.util.Date;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Properties;
import java.util.logging.Logger;
import sg.edu.nus.iss.ooad.jass.dao.IAdvertiserDAO;
import sg.edu.nus.iss.ooad.jass.entity.Advertiser;
import sg.edu.nus.iss.ooad.jass.entity.IJASSEntity;
import sg.edu.nus.iss.ooad.jass.entity.JobAdvertisement;

/**
 *
 * Advertiser Data Access Object for Properties File implementation.
 *
 * @author Isak Rabin (HT082193M)
 * @version 1.0
 * @since 1.0
 *
 * Development Environment : Netbeans IDE v6.7
 * Name of the File        : AdvertiserDAOPropertiesImpl.java
 * Creation / Modification History
 *         Isak Rabin        20-Sep-2009        Created
 *
 */
public class AdvertiserDAOPropertiesImpl extends AbstractPropertiesDAO implements IAdvertiserDAO {

        //Logger
        private final static Logger logger = Logger.getLogger(AdvertiserDAOPropertiesImpl.class.getName());
        //Advertiser Lists
        public static Hashtable<String, IJASSEntity> advertiserCache = new Hashtable<String, IJASSEntity>();
        //Properties filename
        public static final String ADVERTISER_FILE = "data.advertiser.properties";
        //Variable to hold Properties for Advertiser
        public static Properties properties = null;

        //Load at start-up
        static {
                logger.info("Start loading " + ADVERTISER_FILE);
                properties = loadProperties(ADVERTISER_FILE);
                if (properties != null) {
                        Advertiser advertiser = new Advertiser();
                        advertiserCache = advertiser.fromJASSPropertiesFormat(properties);
                }
                logger.info("Finish loading " + ADVERTISER_FILE);
        }

        /**
         * Constructor
         */
        public AdvertiserDAOPropertiesImpl() {
        }

        /**
         * Create new advertiser entity and store it to the persistent data.
         * @param advertiser The advertiser entity.
         * @return True if new advertiser successfully created.
         */
        public synchronized boolean createAdvertiser(Advertiser advertiser) {
                boolean retValue = false;

                //get number to total record
                int iTotalRecord = 0;
                String sTotalRecord = properties.getProperty("NumOfItems");
                if (sTotalRecord != null) {
                        iTotalRecord = Integer.parseInt(sTotalRecord);
                }
                iTotalRecord = iTotalRecord + 1;
                advertiser.setID(String.valueOf(iTotalRecord));

                //update properties
                //ADVERTISER_ATTRIBUTES = {"ID", "UserID", "Name", "Password", "Deleted"};
                properties.put(Advertiser.ADVERTISER_ATTRIBUTES[0] + String.valueOf(iTotalRecord), advertiser.getID());
                properties.put(Advertiser.ADVERTISER_ATTRIBUTES[1] + String.valueOf(iTotalRecord), advertiser.getUserID());
                properties.put(Advertiser.ADVERTISER_ATTRIBUTES[2] + String.valueOf(iTotalRecord), advertiser.getName());
                properties.put(Advertiser.ADVERTISER_ATTRIBUTES[3] + String.valueOf(iTotalRecord), advertiser.getPassword());
                properties.put(Advertiser.ADVERTISER_ATTRIBUTES[4] + String.valueOf(iTotalRecord), advertiser.getDeleted());
                properties.setProperty("NumOfItems", String.valueOf(iTotalRecord));

                //save it and update the cache
                storeProperties(properties, ADVERTISER_FILE);
                advertiserCache.put(advertiser.getID(), advertiser);

                return retValue;
        }

        /**
         * Retrieve advertiser entity from persistent data.
         * @param ID The ID of Advertiser.
         * @return Advertiser object or null if Advertiser cannot be found.
         */
        public Advertiser retrieveAdvertiser(String ID) {
                Advertiser retValue = null;

                retValue = (Advertiser) advertiserCache.get(ID);

                return retValue;
        }

        /**
         * Update existing advertiser.
         * @param advertiser The advertiser entity.
         * @return True if advertiser has successfully updated.
         */
        public synchronized boolean updateAdvertiser(Advertiser advertiser) {
                boolean retValue = false;

                if (advertiserCache.containsKey(advertiser.getID())) {

                        //Get all existing advertisement for this advertiser
                        Advertiser oldAdvertiser = retrieveAdvertiser(advertiser.getID());
                        advertiser.setJobAdvertisement(oldAdvertiser.getJobAdvertisement());

                        //update properties
                        //ADVERTISER_ATTRIBUTES = {"ID", "UserID", "Name", "Password", "Deleted"};
                        properties.setProperty("ID" + advertiser.getID(), advertiser.getID());
                        properties.setProperty("UserID" + advertiser.getID(), advertiser.getUserID());
                        properties.setProperty("Name" + advertiser.getID(), advertiser.getName());
                        properties.setProperty("Password" + advertiser.getID(), advertiser.getPassword());
                        properties.setProperty("Deleted" + advertiser.getID(), advertiser.getDeleted());

                        //save it and update the cache
                        storeProperties(properties, ADVERTISER_FILE);
                        advertiserCache.remove(advertiser.getID());
                        advertiserCache.put(advertiser.getID(), advertiser);

                        //return value
                        retValue = true;
                }

                return retValue;
        }

        /**
         * Mark advertiser as deleted.
         * @param advertiser The advertiser entity.
         * @return True if advertiser has successfully mark as deleted.
         */
        public boolean deleteAdvertiser(Advertiser advertiser) {
                boolean retValue = false;

                if (advertiserCache.containsKey(advertiser.getID())) {

                        //cascade delete --> delete job advertisement belong to this advertiser
                        JobAdvertisementDAOPropertiesImpl jobadvertisementDAO = new JobAdvertisementDAOPropertiesImpl();
                        for (Iterator<JobAdvertisement> i = advertiser.getJobAdvertisement().iterator(); i.hasNext();) {
                                JobAdvertisement jobadvertisement = i.next();
                                jobadvertisementDAO.deleteJobAdvertisement(jobadvertisement);
                        }

                        //update properties
                        advertiser.setDeleted(new Date(System.currentTimeMillis()).toString());
                        advertiserCache.remove(advertiser.getID());
                        properties.setProperty("Deleted" + advertiser.getID(), advertiser.getDeleted());
                        advertiserCache.put(advertiser.getID(), advertiser);

                        retValue = true;
                }


                return retValue;
        }

        /**
         * Retrive advertiser by user id
         * @param UserID
         * @return
         */
        public Advertiser getAdvertiserByUserID(String UserID) {
                Advertiser retValue = new Advertiser();

                //Looping the whole records from cache
                Enumeration<IJASSEntity> elements = advertiserCache.elements();
                while (elements.hasMoreElements()) {
                        Advertiser advertiser = (Advertiser) elements.nextElement();
                        if (advertiser.getUserID().matches(UserID)) {
                                retValue = advertiser;
                                break;
                        }
                }
                return retValue;
        }

        /**
         * Retrieve all advertisers.
         * @return List of advertiser.
         */
        public List<Advertiser> getAllAdvertiser() {
                List<Advertiser> retValue = new ArrayList<Advertiser>();

                //Looping the whole records from cache
                Enumeration<IJASSEntity> elements = advertiserCache.elements();

                while (elements.hasMoreElements()) {
                        Advertiser advertiser = (Advertiser) elements.nextElement();
                        retValue.add(advertiser);
                }

                return retValue;
        }

        /**
         * Cache existing Advertisers from persistent data to the memory.
         * @return
         */
        public static synchronized Hashtable<String, IJASSEntity> cache() {
                return advertiserCache;
        }
}
